home *** CD-ROM | disk | FTP | other *** search
- /* ======== Chatterbox ======= */
-
- #include <AppleTalk.h>
-
- /*** defines */
- #define NULL 0L
- #define MAXUSERS 64
- #define BUFSIZE 600
- #define NONE 0
- #define REGISTER 1
- #define WAITING 2
- #define SCANNING 3
- #define SENDING 4
- #define RECEIVING 5
- #define MAXTEXT 32000L
- #define MAXMSG 50
- #define DISPLINES 8
- #define RETURNKEY '\015'
- #define ENTERKEY '\003'
-
- /*** data about a single user */
- typedef struct UserRecord {
- AddrBlock addr;
- int found;
- } UserRecord;
-
- /*** Globals */
- int DoneFlag; /* true when done */
- WindowPtr TheWindow; /* main window ptr */
- ControlHandle ScanButton; /* button to scan user list */
- ControlHandle SelectAllButton; /* select all button */
- ListHandle UserList; /* list of users currently on the net */
- TEHandle MyMessage; /* message I've typed in */
- TEHandle InMessages; /* messages I've recieved */
- MenuHandle AppleMenu; /* apple menu */
- MenuHandle FileMenu; /* file menu */
- MenuHandle EditMenu; /* edit menu */
- MenuHandle OptionMenu; /* options menu */
- DDPProto **InABRecord; /* holds incomming messages */
- UserRecord OtherUsers[MAXUSERS]; /* addresses of other users */
- EntityName MyEntityName; /* name this process is registered under */
- Ptr MyNameBuf; /* name buffer for this station (used by NBP) */
- Str255 MyName; /* name the user wants to go by */
- int MySocketID; /* socket id of this user */
- int NumOtherUsers; /* number of other users found on the net */
- int TheError; /* for error handling */
- int EchoFlag; /* true if echo-back is turned on */
- int BeepFlag; /* true if beep on receipt turned on */
- int SelectFlag; /* true if auto select new users turned on */
- char RecBuffer[BUFSIZE]; /* buffer for reecieved information */
- Rect StatusR; /* rectangle for status info */
- Rect DragRect; /* used by dragwindow */
-
- /*||||||||||||||||||||*/
- main()
- {
- EventRecord event;
- WindowPtr whichWindow;
- char key;
-
- Initialize ();
- while ( !DoneFlag ) {
-
- GetNextEvent ( everyEvent, &event );
- switch ( event.what ) {
- case activateEvt:
- whichWindow = (WindowPtr) event.message;
- if ( whichWindow == TheWindow ) {
- if ( event.modifiers & activeFlag ) {
- TEActivate ( MyMessage );
- LActivate ( true, UserList );
- ShowControl ( ScanButton );
- ShowControl ( SelectAllButton );
- }
- else {
- TEDeactivate ( MyMessage );
- LActivate ( false, UserList );
- HideControl ( ScanButton );
- HideControl ( SelectAllButton );
- }
- }
- break;
- case updateEvt:
- whichWindow = (WindowPtr) event.message;
- if ( whichWindow == TheWindow ) {
- BeginUpdate ( TheWindow );
- DoUpdate ( );
- EndUpdate ( TheWindow );
- }
- break;
- case mouseDown:
- switch ( FindWindow ( event.where, &whichWindow ) ) {
- case inMenuBar:
- DoMenu ( MenuSelect ( event.where ) );
- break;
- case inSysWindow:
- SystemClick ( &event, whichWindow );
- break;
- case inDrag:
- if ( whichWindow == TheWindow ) DragWindow ( TheWindow, event.where, &DragRect );
- break;
- case inContent:
- if ( whichWindow == TheWindow ) {
- if ( TheWindow != FrontWindow ( ) ) SelectWindow ( TheWindow );
- else DoMouseDown ( event.where, event.modifiers );
- }
- break;
- }
- break;
- case autoKey:
- case keyDown:
- key = (char) (event.message & charCodeMask);
- if ( event.modifiers & cmdKey ) DoMenu ( MenuKey ( key ) );
- else if ( key == RETURNKEY || key == ENTERKEY ) SendMessage ( false );
- else {
- ForeColor ( greenColor );
- TEKey ( key, MyMessage );
- if ( (*MyMessage)->teLength > MAXMSG ) {
- TESetSelect ( (long) MAXMSG, MAXTEXT, MyMessage );
- TEDelete ( MyMessage );
- }
- ForeColor ( blackColor );
- }
- break;
- case nullEvent:
- if ( MySocketID == 0 ) StartAT ( );
- else {
- ShowStatus ( WAITING );
- if ( (*InABRecord)->abResult <= 0 ) ReadMessage ( );
- TEIdle ( MyMessage );
- }
- break;
- }
- }
-
- ByeBye ( );
- }
-
- /*|||||||||||||||||||| initialize the Mac and my globals */
- Initialize ()
- {
- EventRecord event;
- Handle h;
-
- /*** init the mac rom stuff */
- InitGraf ( &thePort );
- InitFonts ();
- InitWindows ();
- InitMenus ();
- TEInit ();
- InitDialogs ( 0L );
- InitCursor ();
- FlushEvents ( everyEvent, 0 );
-
- /*** set up a few globals ... */
- EchoFlag = BeepFlag = SelectFlag = true;
- DoneFlag = false;
- MyNameBuf = 0L;
- InABRecord = (DDPProto **) NewHandle ( sizeof ( DDPProto ) );
- MoveHHi ( InABRecord );
- HLock ( InABRecord );
- DragRect = screenBits.bounds;
- MySocketID = 0;
- NumOtherUsers = 0;
-
- /*** read in the menus */
- AppleMenu = GetMenu ( 1000 );
- InsertMenu ( AppleMenu, 0 );
- AddResMenu ( AppleMenu, 'DRVR' );
- FileMenu = GetMenu ( 1001 );
- InsertMenu ( FileMenu, 0 );
- EditMenu = GetMenu ( 1002 );
- InsertMenu ( EditMenu, 0 );
- OptionMenu = GetMenu ( 1003 );
- InsertMenu ( OptionMenu, 0 );
- DrawMenuBar ();
-
- /*** make sure appletalk is available */
- if ( (TheError = MPPOpen ()) != noErr )
- ErrorAlert ( "\PCan't start AppleTalk, error:", TheError );
-
- /*** get user's name */
- h = (Handle) GetString ( -16096 );
- if ( h != NULL ) BlockMove ( *h, MyName, ((long) **h) + 1L );
- else MyName[0] = 0;
- ReleaseResource ( h );
- NameDlog ( );
-
- /*** open our window & init */
- InitTheWindow ( );
- }
-
- /*|||||||||||||||||||| process menu picks */
- DoMenu ( mResult )
- long mResult;
- {
- int theMenu, theItem, i;
- Str255 daname;
- DialogPtr aboutdlog;
- GrafPtr curport;
- TEHandle te;
-
- theItem = LoWord ( mResult );
- theMenu = HiWord ( mResult );
- switch ( theMenu ) {
- case 1000:
- if ( theItem == 1 ) {
- aboutdlog = GetNewDialog ( 2000, NULL, -1L );
- i = 0;
- while ( !i ) ModalDialog ( NULL, &i );
- DisposDialog ( aboutdlog );
- }
- else {
- GetItem ( AppleMenu, theItem, daname );
- GetPort ( &curport );
- OpenDeskAcc ( daname );
- SetPort ( curport );
- }
- break;
- case 1001:
- if ( theItem == 1 ) DoneFlag = true;
- break;
- case 1002:
- ForeColor ( greenColor );
- switch ( theItem ) {
- case 3:
- TECut ( MyMessage );
- break;
- case 4:
- TECopy ( MyMessage );
- break;
- case 5:
- TEPaste ( MyMessage );
- if ( (*MyMessage)->teLength > MAXMSG ) {
- TESetSelect ( (long) MAXMSG, MAXTEXT, MyMessage );
- TEDelete ( MyMessage );
- }
- break;
- }
- ForeColor ( blackColor );
- break;
- case 1003:
- switch ( theItem ) {
- case 1:
- if ( BeepFlag ) {
- BeepFlag = false;
- CheckItem ( OptionMenu, 1, false );
- }
- else {
- BeepFlag = true;
- CheckItem ( OptionMenu, 1, true );
- }
- break;
- case 2:
- if ( EchoFlag ) {
- EchoFlag = false;
- CheckItem ( OptionMenu, 2, false );
- }
- else {
- EchoFlag = true;
- CheckItem ( OptionMenu, 2, true );
- }
- break;
- case 3:
- if ( SelectFlag ) {
- SelectFlag = false;
- CheckItem ( OptionMenu, 3, false );
- }
- else {
- SelectFlag = true;
- CheckItem ( OptionMenu, 3, true );
- }
- break;
- }
- break;
- }
-
- HiliteMenu(0);
- }
-
- /*|||||||||||||||||||| get the name the user wants to go by */
- NameDlog ( )
- {
- DialogPtr dlog;
- int itype, item;
- Handle h, namefield;
- Rect r;
- Str255 astr;
-
- /*** do the dialog */
- dlog = GetNewDialog ( 1000, 0L, -1L );
- GetDItem ( dlog, 4, &itype, &namefield, &r );
- SetIText ( namefield, MyName );
- SelIText ( dlog, 4, 0, 255 );
- item = 0;
- while ( item != 1 ) ModalDialog ( 0L, &item );
-
- /*** save off the name, 32 chars max */
- GetIText ( namefield, &MyName );
- if ( ((int) *MyName) > 31 ) *MyName = (char) 31;
-
- CloseDialog ( dlog );
- }
-
- /*|||||||||||||||||||| initialize AppleTalk stuff */
- StartAT ( )
- {
- /*** open a socket, use defalut listener */
- if ( (TheError = DDPOpenSocket ( &MySocketID, NULL )) != noErr )
- ErrorAlert ( "\PDDPOpenSocket ( ) returned:", TheError );
-
- /*** register and check for other users, greet everyone */
- RegisterName ( );
- CheckForUsers ( );
- SendGreeting ( );
-
- /*** listen for messages */
- AskForMessage ( );
- }
-
- /*|||||||||||||||||||| Register MyName as a "Chatterbox" via AppleTalk NBP */
- RegisterName ( )
- {
- int len;
- NBPProto **myABRecNBP;
-
- /*** show some feedback */
- ShowStatus ( REGISTER );
-
- /*** make up a handle for registering */
- myABRecNBP = (NBPProto **) NewHandle ( sizeof ( NBPProto ) );
- HLock ( myABRecNBP );
-
- /*** set up our entity name */
- BlockMove ( MyName, MyEntityName.objStr, ((long) *MyName) + 1L );
- BlockMove ( "\PChatterbox", MyEntityName.typeStr, 11L );
- BlockMove ( "\P*", MyEntityName.zoneStr, 2L );
-
- /*** set up a buffer for NBP's internal use */
- len = ((int) *MyName) + 26;
- MyNameBuf = NewPtr ( (long) len );
-
- /*** fill in the record & register */
- (*myABRecNBP)->abOpcode = tNBPRegister;
- (*myABRecNBP)->abUserReference = 0L;
- (*myABRecNBP)->nbpEntityPtr = &MyEntityName;
- (*myABRecNBP)->nbpBufPtr = MyNameBuf;
- (*myABRecNBP)->nbpBufSize = len;
- (*myABRecNBP)->nbpAddress.aSocket = (Byte) MySocketID;
- (*myABRecNBP)->nbpRetransmitInfo.retransInterval = 8;
- (*myABRecNBP)->nbpRetransmitInfo.retransCount = 2;
- if ( (TheError = NBPRegister ( myABRecNBP, false )) != noErr )
- ErrorAlert ( "\PNBPRegister ( ) returned:", TheError );
-
- HUnlock ( myABRecNBP );
- DisposHandle ( myABRecNBP );
- }
-
- /*|||||||||||||||||||| remove the name from NBP */
- UnRegisterName ( )
- {
- if ( (TheError = NBPRemove ( &MyEntityName )) != noErr )
- ErrorAlert ( "\PNBPRemove ( ) returned:", TheError );
- DisposPtr ( MyNameBuf );
- }
-
- /*|||||||||||||||||||| check for other users on the net. */
- CheckForUsers ( )
- {
- int j, r, i, numFound, found, removed;
- Point c;
- EntityName otherEntity;
- NBPProto **otherABRecNBP;
- AddrBlock addblock;
-
- /*** show some feedback */
- ShowStatus ( SCANNING );
-
- /*** mark them all as "not found" */
- for ( i = 0; i < NumOtherUsers; ++i ) OtherUsers[i].found = false;
-
- /*** now scan for other users */
- BlockMove ( "\P=", otherEntity.objStr, 2L );
- BlockMove ( "\PChatterbox", otherEntity.typeStr, 11L );
- BlockMove ( "\P*", otherEntity.zoneStr, 2L );
- otherABRecNBP = (NBPProto **) NewHandle ( sizeof ( NBPProto ) );
- HLock ( otherABRecNBP );
- (*otherABRecNBP)->abOpcode = tNBPLookup;
- (*otherABRecNBP)->abUserReference = 0L;
- (*otherABRecNBP)->nbpEntityPtr = &otherEntity;
- (*otherABRecNBP)->nbpBufPtr = NewPtr ( 4096 );
- (*otherABRecNBP)->nbpBufSize = 4096;
- (*otherABRecNBP)->nbpDataField = 40;
- (*otherABRecNBP)->nbpRetransmitInfo.retransInterval = 8;
- (*otherABRecNBP)->nbpRetransmitInfo.retransCount = 1;
- if ( (TheError = NBPLookup ( otherABRecNBP, false )) != noErr )
- ErrorAlert ( "\PNBPLookup ( ) returned:", TheError );
-
- /*** if we found any, check for them in the list, else empty the list */
- numFound = (*otherABRecNBP)->nbpDataField;
- if ( numFound <= 0 ) {
- j = (*UserList)->dataBounds.bottom;
- if ( j > 0 ) LDelRow ( j, 0, UserList );
- NumOtherUsers = 0;
- }
- else {
- for ( i = 0; i < numFound; ++i ) {
-
- /*** extract it */
- if ( (TheError = NBPExtract ( (*otherABRecNBP)->nbpBufPtr,
- numFound, i+1, &otherEntity, &addblock )) == noErr ) {
-
- /*** see if it's in the list */
- found = false;
- for ( j = 0; j < NumOtherUsers; ++j ) {
- if ( OtherUsers[j].addr.aSocket == addblock.aSocket &&
- OtherUsers[j].addr.aNode == addblock.aNode &&
- OtherUsers[j].addr.aNet == addblock.aNet ) { found = true; break; }
- }
-
- /*** if it is, mark it */
- if ( found ) OtherUsers[j].found = true;
-
- /*** else add it, select it if auto-select is on */
- else {
- c.h = 0;
- c.v = NumOtherUsers;
- OtherUsers[NumOtherUsers].addr = addblock;
- OtherUsers[NumOtherUsers].found = true;
- LAddRow ( 1, NumOtherUsers, UserList );
- LSetCell ( &otherEntity.objStr[1], (int) otherEntity.objStr[0], c, UserList );
- if ( SelectFlag ) LSetSelect ( true, c, UserList );
- ++NumOtherUsers;
- }
-
- /*** don't overflow */
- if ( NumOtherUsers >= MAXUSERS ) break;
- }
- }
-
- /*** delete any that were not found (they've logged off ) */
- for ( j = NumOtherUsers-1; j >= 0; --j ) {
- if ( !OtherUsers[j].found ) {
- --NumOtherUsers;
- BlockMove ( &OtherUsers[j+1], &OtherUsers[j], (long) ((NumOtherUsers-j)*sizeof(UserRecord)) );
- LDelRow ( 1, j, UserList );
- }
- }
- }
-
- DisposPtr ( (*otherABRecNBP)->nbpBufPtr );
- HUnlock ( otherABRecNBP );
- DisposHandle ( otherABRecNBP );
- }
-
- /*|||||||||||||||||||| tell DDP we're waiting for a msg */
- AskForMessage ( )
- {
- (*InABRecord)->abOpcode = tDDPRead;
- (*InABRecord)->abResult = 0;
- (*InABRecord)->abUserReference = 0L;
- (*InABRecord)->ddpType = 5;
- (*InABRecord)->ddpSocket = MySocketID;
- (*InABRecord)->ddpReqCount = BUFSIZE;
- (*InABRecord)->ddpDataPtr = RecBuffer;
- if ( (TheError = DDPRead ( InABRecord, true, true )) != noErr )
- ErrorAlert ( "\PDDPRead ( ) returned:", TheError );
- }
-
- /*|||||||||||||||||||| read a message from the socket */
- ReadMessage ( )
- {
- Rect r;
- Cell c;
- Str255 othername;
- int i, namelen, nlines, fromnode;
-
- /*** make sure there's really a message */
- if ( (*InABRecord)->ddpActCount > 0 ) {
-
- /*** show some feedback */
- ShowStatus ( RECEIVING );
-
- /*** check for users if it's a special message (ie, has option-space) */
- if ( RecBuffer[0] == ' ' ) CheckForUsers ();
-
- /*** see who it's from */
- namelen = 0;
- fromnode = (*InABRecord)->ddpAddress.aNode;
- for ( i = 0; i < NumOtherUsers; ++i ) if ( fromnode == OtherUsers[i].addr.aNode ) break;
- if ( i < NumOtherUsers ) {
- c.h = 0;
- c.v = i;
- namelen = 32;
- LGetCell ( othername, &namelen, c, UserList );
- }
-
- /*** put the message in the display */
- ForeColor ( blueColor );
- TESetSelect ( MAXTEXT, MAXTEXT, InMessages );
- TEInsert ( RecBuffer, (long) (*InABRecord)->ddpActCount, InMessages );
- TEInsert ( " (", 2L, InMessages );
- TEInsert ( othername, (long) namelen, InMessages );
- TEInsert ( ")\015", 2L, InMessages );
- nlines = (*InMessages)->nLines;
- for ( i = DISPLINES; i < nlines; ++i ) DeleteFirstLine ( InMessages );
- ForeColor ( blackColor );
-
- if ( BeepFlag ) SysBeep ( 1 );
- }
- else ErrorAlert ( "\PError in recieved packet.", 0 );
-
- AskForMessage ( );
- }
-
- /*|||||||||||||||||||| send the message out. If toAll is true, send to all, else send to selected. */
- SendMessage ( toAll )
- int toAll;
- {
- DDPProto **outABRecord;
- Handle thetext;
- int i, nlines, textlen, msgSent;
- Cell c;
- char xmitBuffer[BUFSIZE];
-
- /*** only if there is something to say */
- if ( (*MyMessage)->teLength <= 0 ) return;
-
- /*** get a record */
- outABRecord = (DDPProto **) NewHandle ( sizeof ( DDPProto ) );
- HLock ( outABRecord );
-
- /*** copy the text to the out buffer, empty TextEdit record */
- thetext = (Handle) TEGetText ( MyMessage );
- HLock ( thetext );
- textlen = (*MyMessage)->teLength;
- BlockMove ( *thetext, xmitBuffer, textlen );
- HUnlock ( thetext );
-
- /*** send the message to appropriate users */
- for ( msgSent = false, i = 0; i <NumOtherUsers; ++i ) {
- c.h = 0;
- c.v = i;
- if ( toAll || LGetSelect ( false, &c, UserList ) ) {
- ShowStatus ( SENDING );
- (*outABRecord)->abOpcode = tDDPWrite;
- (*outABRecord)->abUserReference = 0L;
- (*outABRecord)->ddpType = 5;
- (*outABRecord)->ddpSocket = MySocketID;
- (*outABRecord)->ddpAddress = OtherUsers[i].addr;
- (*outABRecord)->ddpDataPtr = xmitBuffer;
- (*outABRecord)->ddpReqCount = textlen;
- if ( (TheError = DDPWrite ( outABRecord, false, false )) != noErr )
- ErrorAlert ( "\PDDPWrite ( ) returned:", TheError );
- msgSent = true;
- }
- }
-
- if ( msgSent ) {
- TESetSelect ( 0L, MAXTEXT, MyMessage );
- TEDelete ( MyMessage );
- TESetSelect ( 0L, 0L, MyMessage );
-
- if ( EchoFlag ) {
- ForeColor ( blueColor );
- TESetSelect ( MAXTEXT, MAXTEXT, InMessages );
- TEInsert ( "«", 1L, InMessages );
- TEInsert ( xmitBuffer, (long) textlen, InMessages );
- TEInsert ( "»\015", 2L, InMessages );
- nlines = (*InMessages)->nLines;
- for ( i = DISPLINES; i < nlines; ++i ) DeleteFirstLine ( InMessages );
- ForeColor ( blackColor );
- }
- }
-
- HUnlock ( outABRecord );
- DisposHandle ( outABRecord );
- }
-
- /*|||||||||||||||||||| say hello to existing users */
- SendGreeting ( )
- {
- Str255 greeting;
-
- /*** send log-on messge (has option-space) */
- greeting[0] = '\0';
- Pstrcat ( greeting, "\P Hello Everyone!" );
- TESetSelect ( 0L, 0L, MyMessage );
- TEInsert ( &greeting[1], (long) greeting[0], MyMessage );
- SendMessage ( true );
- TESetSelect ( 0L, MAXTEXT, MyMessage );
- TEDelete ( MyMessage );
- }
-
- /*|||||||||||||||||||| pick up our toys and go home */
- ByeBye ( )
- {
- Str255 adios;
-
- /*** send logoff message (has option-space) */
- adios[0] = '\0';
- Pstrcat ( adios, "\P " );
- Pstrcat ( adios, MyName );
- Pstrcat ( adios, "\P is off!" );
- TESetSelect ( 0L, 0L, MyMessage );
- TEInsert ( &adios[1], (long) adios[0], MyMessage );
- SendMessage ( true );
-
- /*** close everything */
- UnRegisterName ( );
- DDPCloseSocket ( (Byte) MySocketID );
- CloseWindow ( TheWindow );
- }
-
- /*|||||||||||||||||||| delete the first line from the given TEhandle */
- DeleteFirstLine ( te )
- TEHandle te;
- {
- Handle h;
- int charsinline = 0;
- char *cp;
-
- h = TEGetText ( te );
- HLock ( h );
- cp = *h;
- while ( *cp != '\015' ) { ++cp; ++charsinline; }
- ++charsinline;
- TESetSelect ( 0L, (long) charsinline, te );
- TEDelete ( te );
- }
-
- /*|||||||||||||||||||| open and initialize the window */
- InitTheWindow ( )
- {
- Rect r, dbr, view, dest;
- Point csize;
- char title[80];
-
- TheWindow = GetNewWindow ( 1000, 0L, -1L );
- title[0] = '\0';
- Pstrcat ( title, "\PChatterbox - " );
- Pstrcat ( title, MyName );
- SetWTitle ( TheWindow, title );
- SetPort ( TheWindow );
- TextFont ( 4 );
- TextSize ( 9 );
- TextFace ( 0 );
-
- /*** add in the controls */
- ScanButton = GetNewControl ( 1000, TheWindow );
- SelectAllButton = GetNewControl ( 2000, TheWindow );
-
- /*** add in the user list */
- SetRect ( &r, 20, 22, 164, 94 );
- SetRect ( &dbr, 0, 0, 1, 0 );
- csize.v = 12;
- csize.h = 300;
- UserList = LNew ( &r, &dbr, csize, 0, TheWindow, true, false, false, true );
-
- /*** add in the outgoing message field */
- SetRect ( &view, 21, 114, 339, 128 );
- SetRect ( &dest, 22, 115, 338, 270 );
- MyMessage = TENew ( &dest, &view );
- TESetSelect ( 0L, 0L, MyMessage );
-
- /*** set up the incomming message area */
- SetRect ( &view, 21, 148, 339, 238 );
- SetRect ( &dest, 22, 149, 338, 270 );
- InMessages = TENew ( &dest, &view );
- TESetSelect ( 0L, 0L, InMessages );
-
- /*** set up the status area */
- SetRect ( &StatusR, 196, 21, 340, 65 );
- }
-
- /*|||||||||||||||||||| handle update events for our main (and only) window */
- DoUpdate ( )
- {
- Rect r;
- RgnHandle vis;
-
- /*** do the controls */
- SetPort ( TheWindow );
- DrawControls ( TheWindow );
-
- /*** show the user list */
- r = (*UserList)->rView;
- InsetRect ( &r, -1, -1 );
- FrameRect ( &r );
- MoveTo ( r.left, r.top-4 );
- DrawString ( "\PSelect Recipients:" );
- vis = TheWindow->visRgn;
- HandToHand ( &vis );
- LUpdate ( vis, UserList );
- DisposHandle ( vis );
-
- /*** show the MyMessage field */
- r = (*MyMessage)->viewRect;
- MoveTo ( r.left-1, r.top-6 );
- DrawString ( "\PType a message, <return> to send:" );
- EraseRect ( &r );
- InsetRect ( &r, -2, -2 );
- FrameRect ( &r );
- ForeColor ( greenColor );
- TEUpdate ( &r, MyMessage );
- ForeColor ( blackColor );
-
- /*** show the incomming message field */
- r = (*InMessages)->viewRect;
- MoveTo ( r.left-1, r.top-6 );
- DrawString ( "\PReceived Messages:" );
- EraseRect ( &r );
- InsetRect ( &r, -2, -2 );
- FrameRect ( &r );
- ForeColor ( blueColor );
- TEUpdate ( &r, InMessages );
- ForeColor ( blackColor );
-
- /*** show the status area */
- MoveTo ( StatusR.left, StatusR.top-4 );
- DrawString ( "\PStatus:" );
- FrameRect ( &StatusR );
- ShowStatus ( NONE );
- }
-
- /*|||||||||||||||||||| display the status notice */
- ShowStatus ( status )
- int status;
- {
- Rect r;
- char *cp;
- static int oldstatus;
-
- if ( status != oldstatus ) {
- InsetRect ( &StatusR, 2, 2 );
- EraseRect ( &StatusR );
- ForeColor ( redColor );
- cp = NULL;
- switch ( status ) {
- case NONE: break;
- case REGISTER: cp = "\PRegistering on the network."; break;
- case WAITING: cp = "\PListening…"; break;
- case SCANNING: cp = "\PScanning for other users."; break;
- case SENDING: cp = "\PSending message."; break;
- case RECEIVING: cp = "\PReceiving message."; break;
- }
- if ( cp != NULL ) TextBox ( (cp + 1), (long) *cp, &StatusR, teJustLeft );
- ForeColor ( blackColor );
- InsetRect ( &StatusR, -2, -2 );
- oldstatus = status;
- }
- }
-
- /*|||||||||||||||||||| handle mouse-downs in our window */
- DoMouseDown ( thePt, mods )
- Point thePt;
- int mods;
- {
- Rect r;
- Point localPt, c;
- ControlHandle chan;
-
- /*** get the local point */
- localPt = thePt;
- GlobalToLocal ( &localPt );
-
- /*** in UserList or it's scroll bars? */
- r = (*UserList)->rView;
- r.right += 16;
- if ( PtInRect ( localPt, &r ) && ( NumOtherUsers > 0 ) ) {
- LClick ( localPt, mods, UserList );
- return;
- }
-
- /*** in MyMessage ? */
- r = (*MyMessage)->viewRect;
- if ( PtInRect ( localPt, &r ) ) {
- TEClick ( localPt, ((mods & shiftKey) == shiftKey), MyMessage );
- return;
- }
-
- /*** in the controls */
- if ( FindControl ( localPt, TheWindow, &chan ) ) {
- if ( TrackControl ( chan, localPt, NULL ) ) {
- if ( chan == ScanButton ) CheckForUsers ( );
- if ( chan == SelectAllButton ) {
- for ( c.h = 0, c.v = (*UserList)->dataBounds.top; c.v < (*UserList)->dataBounds.bottom; ++c.v )
- LSetSelect ( true, c, UserList );
- }
- }
- }
- }
-
- /*|||||||||||||||||||| catenate the second pascal string to the first */
- Pstrcat ( str1, str2 )
- char *str1, *str2;
- {
- char *str1len, *str1end;
-
- str1len = str1;
- str1end = str1 + (int) *str1len + 1;
- BlockMove ( (str2 + 1), str1end, (long) *str2 );
- *str1len += (int) *str2;
- }
-
- /*|||||||||||||||||||| alert the user to an error, optionally exit to shell */
- ErrorAlert ( where, errorNum )
- char *where;
- int errorNum;
- {
- Str255 idstr;
-
- /*** give the alert */
- NumToString ( (long) errorNum, idstr );
- ParamText ( where, idstr, "\P", "\P" );
-
- if ( Alert ( 666, 0L ) == 1 ) {
- UnRegisterName ( );
- DDPCloseSocket ( (Byte) MySocketID );
- ExitToShell ();
- }
- }
-